/*
 * @(#)CoordinatorImpl.java	1.0 2000/12/14
 *
 * Copyright 2000 Thomas Barnekow. All Rights Reserved.
 *
 * This software is the proprietary information of Thomas Barnekow.
 * Use is subject to license terms.
 */

package tb.jots.impl;

import java.util.*;

import tb.jots.*;

/**
 * {@link Coordinator} implementation.
 *
 * @author Thomas Barnekow
 * @version 1.0
 */
public class CoordinatorImpl implements Coordinator {

  /**
   * {@link Control} object.
   */
  ControlImpl m_control;

  /**
   * Transaction status.
   */
	int m_status;

  /**
   * List of registered resources.
   */
	List m_resources;

  /**
   * Don't let everybody create instances.
   */
	CoordinatorImpl(ControlImpl control) {
    m_control = control;
    m_status = OTS.STATUS_ACTIVE;
    m_resources = Collections.synchronizedList(new ArrayList());
  }

	/*
	 * Coordinator operations
	 */

	public int getStatus() {
		return m_status;
	}

	public boolean isSameTransaction(Coordinator c) {
		return (this == c);
	}

	public void registerResource(Resource r) throws JotsException {
    checkCallingThread();

		if (getStatus() == OTS.STATUS_MARKED_ROLLBACK) {
			throw new TransactionRolledBackException();
		} else if (getStatus() != OTS.STATUS_ACTIVE) {
			throw new InactiveException();
		}

    if (!m_resources.contains(r))
  		m_resources.add(r);
	}

	public void rollbackOnly() throws JotsException	{
    checkCallingThread();
		if (getStatus() > OTS.STATUS_MARKED_ROLLBACK) {
			throw new InactiveException();
		}
		setStatus(OTS.STATUS_MARKED_ROLLBACK);
	}

  /*
   * Implementation-specific operations
   */

	void setStatus(int status) {
		m_status = status;
	}

  Iterator resources() {
    return m_resources.iterator();
  }

	void resetTransactionContext() {
    // Reset (own) Coordinator context
    m_resources.clear();
    m_control = null;
	}

  void checkCallingThread() throws NoPermissionException {
    if (m_control == null) {
      throw new NoPermissionException();
    }
    m_control.checkCallingThread();
  }
}
